﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;

namespace CSE360_SudokuProject
{
    public static class MainGameInputClass
    {
        //variables
        public static UndoStructure[] undoInfoArray = new UndoStructure[3];
        public static Button[,] wrongCellsList = new Button[16, 16];
        public static int wrongAnswerCount;
        public static MainGameScreen9x9 the9x9Board = null;
        public static MainGameScreen16x16 the16x16Board = null;

        static MainGameInputClass()
        {
            //initilizes the undo array
            for (int i = 0; i < 3; i++)
            {
                undoInfoArray[i] = new UndoStructure();
                undoInfoArray[i].undoText = "-1";
                undoInfoArray[i].undoIndexI = -1;
                undoInfoArray[i].undoIndexJ = -1;
                undoInfoArray[i].undoButton = null;
            }

            //inilizes the wrong cell list
            for(int i = 0; i< 16; i++)
                for(int j = 0; j<16; j++)
                {
                    wrongCellsList[i, j] = null;
                }
            wrongAnswerCount = 0;
        }

        public static void SelectButton(Button selectedInput, ref Button highlightedInput, 
            ref int currentSelectedNumber, Color DefaultBackColor)
        {
            //this function highlights the selected button and puts the number/delete into a variable
            //for input to a cell.

            int selectedInputNumberCode = 0;

            #region A-G characters switch
            //switch statement to deal with the A-G characters of 16x16
            switch(selectedInput.Text)
            {
                case "A":
                    selectedInputNumberCode = 10;
                    break;
                case "B":
                    selectedInputNumberCode = 11;
                    break;
                case "C":
                    selectedInputNumberCode = 12;
                    break;
                case "D":
                    selectedInputNumberCode = 13;
                    break;
                case "E":
                    selectedInputNumberCode = 14;
                    break;
                case "F":
                    selectedInputNumberCode = 15;
                    break;
                case "G":
                    selectedInputNumberCode = 16;
                    break;
                case "Delete":
                    selectedInputNumberCode = 17;
                    break;
                default:
                    selectedInputNumberCode = Int32.Parse(selectedInput.Text);
                    break;
            }
            #endregion

            //checks if button is not delete and not currently the same button selected
            if ((selectedInput.Name != "DeleteButton" && selectedInput.Name != "deletebutton")
                && currentSelectedNumber != selectedInputNumberCode)
            {
                //changes selected number and resets old seleted number
                currentSelectedNumber = selectedInputNumberCode;
                highlightedInput.BackColor = Color.Black;
                highlightedInput = selectedInput;
                highlightedInput.BackColor = System.Drawing.Color.LightBlue;
            }
                //checks if button is delete button and not currently the delete button
            else if ((selectedInput.Name == "DeleteButton" || selectedInput.Name == "deletebutton")
                && currentSelectedNumber != selectedInputNumberCode)
            {
                //changes the selected number and resets old selected number
                currentSelectedNumber = 17;
                highlightedInput.BackColor = Color.Black;
                highlightedInput = selectedInput;
                highlightedInput.BackColor = System.Drawing.Color.LightBlue;
            }
            else
            {
                //the same number is selected..
                //unselecteds the number and resets the color of the button
                currentSelectedNumber = 0;
                highlightedInput.BackColor = Color.Black;
            }
        }

        public static void InputAnswer(Button selectedCell, int currentSelectedNumber, int i, int j)
        {
            //this function inputs/removes the number in the selected cell base off the selected input.

            string currentSelectedNumberCode = "";

            #region A-G characters switch
            //switch statement to deal with the A-G characters of 16x16
            switch (currentSelectedNumber)
            {
                case 10:
                    currentSelectedNumberCode = "A";
                    break;
                case 11:
                    currentSelectedNumberCode = "B";
                    break;
                case 12:
                    currentSelectedNumberCode = "C";
                    break;
                case 13:
                    currentSelectedNumberCode = "D";
                    break;
                case 14:
                    currentSelectedNumberCode = "E";
                    break;
                case 15:
                    currentSelectedNumberCode = "F";
                    break;
                case 16:
                    currentSelectedNumberCode = "G";
                    break;
                default:
                    currentSelectedNumberCode = currentSelectedNumber.ToString();
                    break;
            }
            #endregion

            //checks if the selected button is delete and 
            //the selected cell is not already empty
            if (currentSelectedNumber == 17 && selectedCell.Text.CompareTo("") != 0)
            {
                //updates undo and changes the cells text
                UpdateUndo(selectedCell, i, j);
                selectedCell.Text = "";
                //updates the correct current board data
                if(ThePuzzleGenerator.is9x9)
                    ThePuzzleGenerator.BoardCurrent9x9[i, j] = 0;
                else if(ThePuzzleGenerator.is16x16)
                    ThePuzzleGenerator.BoardCurrent16x16[i, j] = 0;
                //added the cell to wrong cell list and count
                wrongCellsList[i, j] = selectedCell;
                wrongAnswerCount++;
            }
                //checks if the selected button is not delete and 
                //the selected cell is not already that number
            else if (currentSelectedNumber != 0 && selectedCell.Text.CompareTo(currentSelectedNumberCode) != 0)
            {
                //updates undo and changes the cells text
                UpdateUndo(selectedCell, i, j);
                selectedCell.Text = currentSelectedNumberCode;
                //updates the correct current board data and 
                if (ThePuzzleGenerator.is9x9)
                {
                    ThePuzzleGenerator.BoardCurrent9x9[i, j] = Convert.ToByte(currentSelectedNumber);
                    //checks if the answer is correct
                    if (ThePuzzleGenerator.BoardCurrent9x9[i, j].CompareTo(ThePuzzleGenerator.BoardAnswer9x9[i, j]) == 0)
                    {
                        wrongCellsList[i, j] = null;
                        wrongAnswerCount--;
                        FileManager.currentScore += 30;
                    }
                    else
                    {
                        if (wrongCellsList[i, j] == null)
                        {
                            wrongCellsList[i, j] = selectedCell;
                            wrongAnswerCount++;
                        }
                        FileManager.currentScore -= 15;
                    }
                    //forces board to redraw board
                    the9x9Board.Refresh();

                    //checks if the puzzle is solved
                    //if so lets the form closing method handel it
                    if (wrongAnswerCount <= 0)
                    {
                        System.Threading.Thread.Sleep(1000);
                        the9x9Board.Close();
                    }
                }
                else if(ThePuzzleGenerator.is16x16)
                {
                    ThePuzzleGenerator.BoardCurrent16x16[i, j] = Convert.ToByte(currentSelectedNumber);
                    //checks if the answer is correct
                    if (ThePuzzleGenerator.BoardCurrent16x16[i, j].CompareTo(ThePuzzleGenerator.BoardAnswer16x16[i, j]) == 0)
                    {
                        wrongCellsList[i, j] = null;
                        wrongAnswerCount--;
                        FileManager.currentScore += 50;
                    }
                    else
                    {
                        if (wrongCellsList[i, j] == null)
                        {
                            wrongCellsList[i, j] = selectedCell;
                            wrongAnswerCount++;
                        }
                        FileManager.currentScore -= 25;
                    }
                    //forces board to redraw board
                    the16x16Board.Refresh();

                    //checks if the puzzle is solved
                    //if so lets the form closing method handel it
                    if (wrongAnswerCount <= 0)
                    {
                        System.Threading.Thread.Sleep(1000);
                        the16x16Board.Close();
                    }

                }
            }
        }

        public static void UpdateUndo(Button selectedCell, int i, int j)
        {
            //adds the new button to the struct array and shifts accordingly
            undoInfoArray[2].undoButton = undoInfoArray[1].undoButton;
            undoInfoArray[1].undoButton = undoInfoArray[0].undoButton;
            undoInfoArray[0].undoButton = selectedCell;

            //adds the new button text to the struct array and shifts accordingly
            undoInfoArray[2].undoText = undoInfoArray[1].undoText;
            undoInfoArray[1].undoText = undoInfoArray[0].undoText;
            undoInfoArray[0].undoText = selectedCell.Text;

            //adds the new button i index to the struct array and shifts accordingly
            undoInfoArray[2].undoIndexI = undoInfoArray[1].undoIndexI;
            undoInfoArray[1].undoIndexI = undoInfoArray[0].undoIndexI;
            undoInfoArray[0].undoIndexI = i;

            //adds the new button j index to the struct array and shifts accordingly
            undoInfoArray[2].undoIndexJ = undoInfoArray[1].undoIndexJ;
            undoInfoArray[1].undoIndexJ = undoInfoArray[0].undoIndexJ;
            undoInfoArray[0].undoIndexJ = j;
        }

        public static void UndoButton_Clicked()
        {
            //checks if the undo button has hit the limit (3 spaces back)
            if (undoInfoArray[0].undoButton != null)
            {
                //resets the text back
                undoInfoArray[0].undoButton.Text =
                        undoInfoArray[0].undoText;

                //checks if board is 9x9
                if (ThePuzzleGenerator.is9x9)
                {
                    #region 9x9 current board update
                    //checks if cells is being set to a blank or not
                    if (undoInfoArray[0].undoButton.Text.CompareTo("") == 0)
                    {
                        //sets the current board to 0 (the blank number)
                        ThePuzzleGenerator.BoardCurrent9x9
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] =
                            Convert.ToByte(0);
                    }
                    else
                    {
                        //sets the current board to the previous answer
                        ThePuzzleGenerator.BoardCurrent9x9
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] =
                            Convert.ToByte(undoInfoArray[0].undoButton.Text);
                    }
                    #endregion

                    #region 9x9 wrong cell list
                    //checks if the current board spot is equal to the answer board spot
                    if (ThePuzzleGenerator.BoardCurrent9x9
                    [undoInfoArray[0].undoIndexI,
                    undoInfoArray[0].undoIndexJ].CompareTo(
                    ThePuzzleGenerator.BoardAnswer9x9
                    [undoInfoArray[0].undoIndexI,
                    undoInfoArray[0].undoIndexJ]) == 0)
                    {
                        //if so removes it from the wrong list and reduces the count
                        wrongCellsList
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] = null;
                        wrongAnswerCount--;
                    }
                    else
                    {
                        //if not adds the cell to the wrong list and increses the count
                        wrongCellsList
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] =
                                undoInfoArray[0].undoButton;
                        wrongAnswerCount++;
                    }
                    //forces board to redraw board
                    the9x9Board.Refresh();

                    //checks if the puzzle is solved
                    //if so lets the form closing method handel it
                    if (wrongAnswerCount <= 0)
                    {                       
                        System.Threading.Thread.Sleep(1000);
                        the9x9Board.Close();
                    }
                    #endregion
                }
                //checks if board is 16x16
                else if(ThePuzzleGenerator.is16x16)
                {
                    int selectedInputNumberCode = 0;

                    #region A-G characters switch
                    //switch statement to deal with the A-G characters of 16x16
                    switch (undoInfoArray[0].undoButton.Text)
                    {
                        case "A":
                            selectedInputNumberCode = 10;
                            break;
                        case "B":
                            selectedInputNumberCode = 11;
                            break;
                        case "C":
                            selectedInputNumberCode = 12;
                            break;
                        case "D":
                            selectedInputNumberCode = 13;
                            break;
                        case "E":
                            selectedInputNumberCode = 14;
                            break;
                        case "F":
                            selectedInputNumberCode = 15;
                            break;
                        case "G":
                            selectedInputNumberCode = 16;
                            break;
                        case "":
                            selectedInputNumberCode = 0;
                            break;
                        default:
                            selectedInputNumberCode = Int32.Parse(undoInfoArray[0].undoButton.Text);
                            break;
                    }
                    #endregion

                    #region 16x16 current board update
                    //checks if cells is being set to a blank or not
                    if (selectedInputNumberCode == 0)
                    {
                        //sets the current board to 0 (the blank number)
                        ThePuzzleGenerator.BoardCurrent16x16
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] =
                            Convert.ToByte(0);
                    }
                    else
                    {
                        //sets the current board to the previous answer
                        ThePuzzleGenerator.BoardCurrent16x16
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] =
                            Convert.ToByte(selectedInputNumberCode);
                    }
                    #endregion

                    #region 16x16 wrong cell list
                    //checks if the current board spot is equal to the answer board spot
                    if (ThePuzzleGenerator.BoardCurrent16x16
                    [undoInfoArray[0].undoIndexI,
                    undoInfoArray[0].undoIndexJ].CompareTo(
                    ThePuzzleGenerator.BoardAnswer16x16
                    [undoInfoArray[0].undoIndexI,
                    undoInfoArray[0].undoIndexJ]) == 0)
                    {
                        //if so removes it from the wrong list and reduces the count
                        wrongCellsList
                        [undoInfoArray[0].undoIndexI,
                        undoInfoArray[0].undoIndexJ] = null;
                        wrongAnswerCount--;
                    }
                    else
                    {
                        //if not adds the cell to the wrong list and increses the count
                        wrongCellsList
                            [undoInfoArray[0].undoIndexI,
                            undoInfoArray[0].undoIndexJ] =
                                undoInfoArray[0].undoButton;

                        wrongAnswerCount++;
                    }
                    //forces board to redraw board
                    the16x16Board.Refresh();

                    //checks if the puzzle is solved
                    //if so lets the form closing method handel it
                    if (wrongAnswerCount <= 0)
                    {                      
                        System.Threading.Thread.Sleep(1000);
                        the16x16Board.Close();
                    }
                    #endregion
                }

                //removes the used button from the struct array and shifts accordingly
                undoInfoArray[0].undoButton = undoInfoArray[1].undoButton;
                undoInfoArray[1].undoButton = undoInfoArray[2].undoButton;
                undoInfoArray[2].undoButton = null;

                //removes the used button text from the struct array and shifts accordingly
                undoInfoArray[0].undoText = undoInfoArray[1].undoText;
                undoInfoArray[1].undoText = undoInfoArray[2].undoText;
                undoInfoArray[2].undoText = "-1";

                //removes the used button i index from the struct array and shifts accordingly
                undoInfoArray[0].undoIndexI = undoInfoArray[1].undoIndexI;
                undoInfoArray[1].undoIndexI = undoInfoArray[2].undoIndexI;
                undoInfoArray[2].undoIndexI = -1;

                //removes the used button j index from the struct array and shifts accordingly
                undoInfoArray[0].undoIndexJ = undoInfoArray[1].undoIndexJ;
                undoInfoArray[1].undoIndexJ = undoInfoArray[2].undoIndexJ;
                undoInfoArray[2].undoIndexJ = -1;
            }

            //message for if the undo button has hit the limit (3 spaces back)
            else
                MessageBox.Show("Undo end hit");
        }
    }
}
